package com.quyunshuo.module.home.activity.result

import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.Canvas
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.os.Handler
import android.os.Looper
import android.os.VibrationEffect
import android.os.Vibrator
import android.os.VibratorManager
import android.view.View
import android.widget.Toast
import androidx.activity.viewModels
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.lifecycle.lifecycleScope
import com.quyunshuo.edwinpro.common.ui.BaseActivity
import com.quyunshuo.module.home.activity.concentration.ConcentrationActivity
import com.quyunshuo.module.home.activity.concentration.ConcentrationViewModel
import com.quyunshuo.module.home.databinding.HomeActivityConcentrationBinding
import com.quyunshuo.module.home.databinding.HomeActivityResultBinding
import com.quyunshuo.module.home.room.database.SumDataBase
import com.quyunshuo.module.home.room.entity.ConcentrationEntity
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
import java.io.File
import java.io.FileOutputStream
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
import java.util.Locale
import java.util.concurrent.TimeUnit

@AndroidEntryPoint
class ResultActivity :
    BaseActivity<HomeActivityResultBinding, ConcentrationViewModel>() {

    val concentrationDao by lazy { SumDataBase.getInstance().concentrationDao() }

    //震动
    private var isVibrating = false
    private lateinit var vibrator: Vibrator
    private lateinit var vibrationPattern: LongArray

    // 时间格式化工具
    private val hourFormat = SimpleDateFormat("HH", Locale.getDefault())
    private val minuteFormat = SimpleDateFormat("mm", Locale.getDefault())

    companion object {
        private const val STORAGE_PERMISSION_CODE = 101
        fun newInstance(context: Context, minutes: Long) {

            context.startActivity(Intent(context, ResultActivity::class.java).apply {
                putExtra("minutes", minutes)
            })
        }
    }

    private val totalMinutes by lazy {
        intent.getLongExtra("minutes", 1)
    }

    // 时间更新处理器
    private val handler = Handler(Looper.getMainLooper())
    private val updateRunnable = object : Runnable {
        override fun run() {
            updateTime()
            handler.postDelayed(this, TimeUnit.SECONDS.toMillis(30)) // 每30秒更新一次
        }
    }


    /**
     * 通过 viewModels() + Hilt 获取 ViewModel 实例
     */
    override val mViewModel by viewModels<ConcentrationViewModel>()


    override fun createVB() = HomeActivityResultBinding.inflate(layoutInflater)


    @SuppressLint("ClickableViewAccessibility")
    override fun HomeActivityResultBinding.initView() {


        // 初始化震动器
        vibrator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            val vibratorManager = getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager
            vibratorManager.defaultVibrator
        } else {
            @Suppress("DEPRECATION")
            getSystemService(VIBRATOR_SERVICE) as Vibrator
        }
        // 默认震动模式：0表示立即开始震动1秒，停止1秒
        vibrationPattern = longArrayOf(0, 1000, 1000)
        startVibration()

    }

    private fun startVibration() {
        if (isVibrating) return

        isVibrating = true

        // 创建震动效果
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            // API 26+ - 使用VibrationEffect
            val effect = VibrationEffect.createWaveform(vibrationPattern, 0)
            vibrator.vibrate(effect)
        } else {
            // 旧版本API
            @Suppress("DEPRECATION")
            vibrator.vibrate(vibrationPattern, 0)
        }
    }

    private fun stopVibration() {
        if (!isVibrating) return
        vibrator.cancel()
        isVibrating = false
    }

    override fun onPause() {
        stopVibration()//结束
        super.onPause()
    }


    override fun HomeActivityResultBinding.initListener() {
        sleep.setOnClickListener {
            ConcentrationActivity.newInstance(this@ResultActivity,totalMinutes.toLong())
            finish()
        }
        startUp.setOnClickListener {
            onBackPressed()
        }
        down.setOnClickListener {
            checkPermissionsAndCapture()
        }

    }

    private fun checkPermissionsAndCapture() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            // Android 13+ (API 33) 使用新的权限系统
            if (ContextCompat.checkSelfPermission(
                    this,
                    android.Manifest.permission.READ_MEDIA_IMAGES
                ) == PackageManager.PERMISSION_GRANTED
            ) {
                captureAndSave()
            } else {
                ActivityCompat.requestPermissions(
                    this,
                    arrayOf(android.Manifest.permission.READ_MEDIA_IMAGES),
                    STORAGE_PERMISSION_CODE
                )
            }
        } else {
            // Android 12 及以下版本
            if (ContextCompat.checkSelfPermission(
                    this,
                    android.Manifest.permission.WRITE_EXTERNAL_STORAGE
                ) == PackageManager.PERMISSION_GRANTED
            ) {
                captureAndSave()
            } else {
                ActivityCompat.requestPermissions(
                    this,
                    arrayOf(android.Manifest.permission.WRITE_EXTERNAL_STORAGE),
                    STORAGE_PERMISSION_CODE
                )
            }
        }
    }

    override fun initObserve() {


    }

    override fun initRequestData() {
        lifecycleScope.launch {
            concentrationDao.insert(ConcentrationEntity(durationMinutes = totalMinutes.toInt()))

        }
    }



    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
        // 立即更新一次时间
        updateTime()
        // 开始定期更新
        handler.postDelayed(updateRunnable, TimeUnit.SECONDS.toMillis(30))
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        // 移除更新回调，防止内存泄漏
        handler.removeCallbacks(updateRunnable)
    }

    private fun updateTime() {
        val calendar = Calendar.getInstance()
        val currentHour = hourFormat.format(calendar.time)
        val currentMinute = minuteFormat.format(calendar.time)

        // 将小时和分钟分别设置到两个TextView
        mBinding.hour.text = currentHour
        mBinding.minute.text = currentMinute

    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == STORAGE_PERMISSION_CODE) {
            if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                captureAndSave()
            } else {
                Toast.makeText(
                    this,
                    "权限被拒绝，无法保存图片",
                    Toast.LENGTH_SHORT
                ).show()
            }
        }
    }

    private fun captureAndSave() {
        // 获取窗口的根视图（DecorView的根视图），包含整个窗口内容
        val rootView: View = window.decorView.rootView

        // 调用截图方法获取当前界面的Bitmap
        val bitmap = getScreenShot(rootView)

        // 检查是否成功获取Bitmap
        if (bitmap != null) {
            // 尝试保存图片到相册
            val saved = saveBitmapToGallery(bitmap)

            // 根据保存结果显示提示信息
            if (saved) {
                Toast.makeText(
                    this,
                    "图片已保存到相册",
                    Toast.LENGTH_LONG  // 长时间显示成功提示
                ).show()
            } else {
                Toast.makeText(
                    this,
                    "保存失败，请重试",
                    Toast.LENGTH_SHORT  // 短时间显示失败提示
                ).show()
            }
        }
    }

    /**
     * 获取指定视图的截图
     * @param view 要截图的视图
     * @return 截取的Bitmap对象，如果失败则返回null
     */
    private fun getScreenShot(view: View): Bitmap? {
        val inflate = HomeActivityConcentrationBinding.inflate(layoutInflater)
        // 创建一个与视图相同尺寸的Bitmap
        val screenshot = Bitmap.createBitmap(
            view.width,       // 视图宽度
            view.height,      // 视图高度
            Bitmap.Config.ARGB_8888  // 使用ARGB_8888配置保证高质量
        )

        // 创建一个画布，将视图绘制到Bitmap上
        val canvas = Canvas(screenshot)
        view.draw(canvas)  // 将视图内容绘制到画布上
        inflate.root.draw(canvas)
        return screenshot
    }

    /**
     * 保存Bitmap到相册
     * @param bitmap 要保存的图片
     * @return 保存成功返回true，否则返回false
     */
    private fun saveBitmapToGallery(bitmap: Bitmap): Boolean {
        // 创建日期格式化器，用于生成唯一的文件名
        val dateFormat = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault())
        // 生成基于当前时间的文件名，格式：SCREENSHOT_20230726_150430.png
        val filename = "SCREENSHOT_${dateFormat.format(Date())}.png"

        // 指定保存目录：DCIM/Screenshots（这是系统默认的截图目录）
        val storageDir = File(
            Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM),
            "Screenshots"
        )

        // 如果目录不存在则创建它（mkdirs会创建所有缺失的父目录）
        if (!storageDir.exists()) {
            storageDir.mkdirs()  // 创建目录（包括所有必要的父目录）
        }

        // 创建目标文件
        val imageFile = File(storageDir, filename)

        return try {
            // 使用try-with-resources确保流正确关闭
            FileOutputStream(imageFile).use { out ->
                // 将Bitmap以PNG格式压缩输出（100表示最高质量）
                bitmap.compress(Bitmap.CompressFormat.PNG, 100, out)
            }

            // 通知系统媒体扫描器扫描新文件，使其在相册中可见
            scanMedia(imageFile)
            true  // 保存成功返回true
        } catch (e: Exception) {
            // 捕获并打印所有异常
            e.printStackTrace()
            false  // 保存失败返回false
        }
    }

    /**
     * 通知系统扫描新文件
     * @param file 要扫描的文件
     */
    private fun scanMedia(file: File) {
        // 创建一个广播，通知系统扫描指定的媒体文件
        val mediaScanIntent = Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE)
        // 将文件路径转换为URI并放入Intent中
        mediaScanIntent.data = Uri.fromFile(file)
        // 发送广播通知系统
        sendBroadcast(mediaScanIntent)
    }
}